import {createStore, designComponent, designPage, onMounted, PropType, reactive} from "@peryl/react-compose";
import {Alert, AutoTable, LoadingMask, PageCard, PageCardContent, Plc, PlcDate, PlcInput, PlcNumber, PlcTime, Tab, TabGroup} from "plain-design";
import {http} from "../../modules/plain-design/http";
import {useTableOption} from "../../modules/plain-design/useTableOption";
import {env} from "../../env";

export default designPage(() => {

  const currentTab = createStore({
    initialState: '',
    getCacheConfig: () => ({
      envName: env.envName,
      cacheName: 'general-module-page-tabs'
    }),
  });

  const state = reactive({
    modules: [] as any[],
    loading: true,
  });

  onMounted(async () => {
    const data = await http.post<{ list: any[] }>('/module/list', { all: true });
    state.modules = data.list;
    state.loading = false;
  });

  const ModulePage = designComponent({
    props: {
      moduleRow: { type: Object as PropType<Record<string, any>>, required: true },
    },
    setup({ props }) {

      const module = props.moduleRow.code;
      const moduleConfig = (() => {
        if (!module) {
          return 'missing require module code!';
        }
        try {
          return JSON.parse(props.moduleRow.moduleConfig);
        } catch (e) {
          return 'json parse module config failed!';
        }
      })();

      if (typeof moduleConfig === "string") {
        return () => (
          <Alert label={moduleConfig} status="error"/>
        );
      }

      const option = useTableOption({
        url: module,
        fill: true,
      });

      return () => {
        return (
          <AutoTable option={option}>
            {Object.entries(moduleConfig.columns).map(([humpName, columnInfo]: [string, any]) => {
              const publicAttrs = {
                key: humpName,
                field: humpName,
                title: columnInfo.front?.title || humpName,
                editable: ['id', 'createdAt', 'createdBy', 'updatedAt', 'updatedBy'].indexOf(humpName) === -1
              };
              switch (columnInfo.valueType) {
                case 'string':
                  return <PlcInput {...publicAttrs} overflowTooltip/>;
                case 'number':
                  return <PlcNumber {...publicAttrs}/>;
                case 'date':
                  return <PlcDate {...publicAttrs}/>;
                case 'time':
                  return <PlcTime {...publicAttrs}/>;
                case 'datetime':
                  return <PlcDate {...publicAttrs} datetime width={150}/>;
              }
              return <Plc key={humpName} field={humpName} title={columnInfo.front?.title || humpName}/>;
            })}
          </AutoTable>
        );
      };
    },
  });

  return () => (
    state.loading ? (
      <PageCard full>
        <PageCardContent full>
          <LoadingMask modelValue/>
        </PageCardContent>
      </PageCard>
    ) : (
      <PageCard full>
        <PageCardContent full>
          <TabGroup v-model={currentTab.value} fitHeight>
            {state.modules.map(item => (
              <Tab title={item.label} key={item.code} destroyOnHide>
                <ModulePage moduleRow={item}/>
              </Tab>
            ))}
          </TabGroup>
        </PageCardContent>
      </PageCard>
    )
  );

});
